--[[
   Copyright (c) 2012 TPV R&D Center Brazil
   All rights reserved
 
   FileName: app.channel
 
   Created by: Guilherme Guimarães
   Date: 07/26/2012
--]]
------------------------------------------------------------------------
--local variables
local tScanStatus = {}
local tPrefenceApp = require('preference')
local tAudioApp = require('audio')
local tCaptionApp = require('caption')
require('basicZapper')
--channel List
local tChannelList = {}
local tLastChannel = {}
local tFavoritList = {}
local bIsBlock = false
local bIsParental = false
local sTempParental = 'OFF'
local nCurrParental = 'L'
local bIsNoSignal = false
local bIsNoTransmission = false
local bIsTuning = false

------------------------------------------------------------------------
--module table
--module Channel - responsible of all operations related to channel,
--such as channel list, favorites, block, skip, tuner mode.
local tChannelApp = {}
------------------------------------------------------------------------
--module functions
--- Get available tuner modes
-- @return a table of strings with available tuner modes.
function tChannelApp.resetBlocks()
   bIsBlock = false
   bIsNoSignal = false
   bIsNoTransmission = false
   bIsParental = false
end

function tChannelApp.isTuning()
   return bIsTuning
end

--module functions
--- Get available tuner modes
-- @return a table of strings with available tuner modes.
function tChannelApp.getAvailableTunerModes()
   return {'Air','Cable'}
end

--- Get current tuner mode
-- @param a string with new tuner mode.
-- @return a boolean to indicate if have channels at tuner mode
function tChannelApp.setCurrentTunerMode(sTunerMode)
   local bHasChannel = false
   if (bIsBlock) then
      bIsBlock = false
      tChannelApp.tGuiHandlers.onStopBlock()
   end
   tPrefenceApp.setTunerMode(sTunerMode) --@TODO
   tChannelApp.updateChannelList(sTunerMode)
   if (#tChannelList > 0) then
      bHasChannel = true
      tChannelApp.tuneDefaultChannel()
   else
      tChannelApp.tuneNoChannel()
   end
   return bHasChannel
end

--- Get current tuner mode
-- @return a string with current tuner mode.
function tChannelApp.getCurrentTunerMode()
   local tRet = tPrefenceApp.getTunerMode() --@TODO
   if (type(tRet) == 'table') then
      return tRet[1]
   else
      return tRet
   end
end

--- Get current tuner mode
-- @return boolean True if the command was sent successfully, false if some error occured.
function tChannelApp.tuneDefaultChannel()
   local bRet
   local tDefault = {}
   local nI = 1
   tCaptionApp.setCaption(0)
   if (tChannelApp.getCurrentTunerMode() == 'Air') then
      while ((nI < #tChannelList) and (not tDefault.nId)) do
         if (tChannelList[nI][1].bIsDigital == true) then
            tDefault = tChannelList[nI][1]
         end
         nI = nI + 1
      end
      if (tDefault.nId) then
         --first digital
         tChannelApp.tGuiHandlers.onResetAdvice()
         tChannelApp.resetBlocks()
         tChannelApp.checkBlocked(tDefault)
         tChannelApp.clearParentalTempUnblock()
         control.muteVideo(0,{r=0,g=0,b=0})
         bRet = control.selectChannel(tDefault.nId)
         bIsTuning = true
         tChannelApp.checkParental('L')
         tPrefenceApp.setLastChanId(tDefault.nId)
      else
         --first of the list
         tChannelApp.tGuiHandlers.onResetAdvice()
         tChannelApp.resetBlocks()
         tChannelApp.checkBlocked(tChannelList[1][1])
         tChannelApp.clearParentalTempUnblock()
         control.muteVideo(0,{r=0,g=0,b=0})
         bRet = control.selectChannel(tChannelList[1][1].nId)
         bIsTuning = true
         tChannelApp.checkParental('L')
         tPrefenceApp.setLastChanId(tChannelList[1][1].nId)
      end
   else
      --case of cable, tune first channel
      tChannelApp.tGuiHandlers.onResetAdvice()
      tChannelApp.resetBlocks()
      tChannelApp.checkBlocked(tChannelList[1][1])
      tChannelApp.clearParentalTempUnblock()
      control.muteVideo(0,{r=0,g=0,b=0})
      bRet = control.selectChannel(tChannelList[1][1].nId)
      bIsTuning = true
      tChannelApp.checkParental('L')
      tPrefenceApp.setLastChanId(tChannelList[1][1].nId)
   end
   tChannelApp.tGuiHandlers.onStopAutoOff()
   return bRet
end

--- Function to get the channel list size
-- @return A number with the size of the channels list
function tChannelApp.getSignalLevel()
   return control.getSignalLevel ()
end

--- Function to get the channel list size
-- @return A number with the size of the channels list
function tChannelApp.getChannelListSize()
	ChannelList = channels.getChannelList()	
   return #ChannelList
end

--- Function to get the channel list
-- @return A table of channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.getChannelList()
	ChannelList = channels.getChannelList()	
   return ChannelList   
end

--- Function to get the favorite channels list
-- @return A table with the favorite channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.updateChannel(tChannel, bIsSkip, bIsBlock, bIsFavorite)
   local nFound
   for nI = 1, #tChannelList do
      if (tChannelList[nI][1].nNumber == tChannel.nNumber) then
         nFound = nI
         for nJ = 1, #tChannelList[nI] do
            tChannelList[nI][nJ].bIsSkipped = bIsSkip
            tChannelList[nI][nJ].bIsBlock = bIsBlock
            tChannelList[nI][nJ].bIsFavorite = bIsFavorite
            if (tChannelList[nI][nJ].nId == tChannelApp.getCurrentChannel().nId ) then
               tChannelApp.checkBlocked(tChannelList[nI][nJ])
            end
            local tMask = {['id'] = tChannelList[nI][nJ].nId} --tFilterMask fields not follow Guideline because is sent to TvStack directly
            local tUpdateChannel = channels.getChannelList(tMask)
            tUpdateChannel[1].skipped = bIsSkip
            tUpdateChannel[1].blocked = bIsBlock
            tUpdateChannel[1].favorite = bIsFavorite
            channels.saveChannel(tUpdateChannel[1])
         end
      end
   end
   if (#tFavoritList > 1) then
      for nI = 1, #tFavoritList do
         if (tFavoritList[nI][1].nNumber == tChannel.nNumber) then
            bFound = true
            if (not bIsFavorite) then
               table.remove(tFavoritList, nI)
               break
            end
         end
      end
   elseif (#tFavoritList == 1) then
      if (tFavoritList[1][1].nNumber == tChannel.nNumber) then
         bFound = true
         if (not bIsFavorite) then
            tFavoritList = {}
            return tFavoritList
         end
      end
   end
   if (bIsFavorite and (not bFound)) then
      nPos = 0
      if (#tFavoritList > 1) then
         --table.sort(tFavoritList, function(tA,tB) return tA[1][1].nNumber < tB[1][1].nNumber end)
         for nI = 1, #tFavoritList do
            if (tChannelList[nFound][1].nNumber < tFavoritList[nI][1].nNumber) then
               nPos = nI
               break
            end
         end
      end
      if (nPos == 0) then
         table.insert(tFavoritList, tChannelList[nFound])
      else
         table.insert(tFavoritList, nPos, tChannelList[nFound])
      end
   end
   return tFavoritList
end

--- Function to get the favorite channels list
-- @return A table with the favorite channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.setSkipChannel(tChannel, bIsSkip)
   for nI = 1, #tChannelList do
      if (tChannelList[nI][1].nNumber == tChannel.nNumber) then
         for nJ = 1, #tChannelList[nI] do
            tChannelList[nI][nJ].bIsSkipped = bIsSkip
            local tMask = {['id'] = tChannelList[nI][nJ].nId} --tFilterMask fields not follow Guideline because is sent to TvStack directly
            local tUpdateChannel = channels.getChannelList(tMask)
            tUpdateChannel[1].skipped = bIsSkip
            channels.saveChannel(tUpdateChannel[1])
         end
      end
   end
end

--- Function to get the favorite channels list
-- @return A table with the favorite channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.setBlockChannel(tChannel, bIsBlock)
   local nFound
   for nI = 1, #tChannelList do
      if (tChannelList[nI][1].nNumber == tChannel.nNumber) then
         for nJ = 1, #tChannelList[nI] do
            tChannelList[nI][nJ].bIsBlock = bIsBlock
            if (tChannelList[nI][nJ].nId == tChannelApp.getCurrentChannel().nId ) then
               tChannelApp.checkBlocked(tChannelList[nI][nJ])
            end
            local tMask = {['id'] = tChannelList[nI][nJ].nId} --tFilterMask fields not follow Guideline because is sent to TvStack directly
            local tUpdateChannel = channels.getChannelList(tMask)
            tUpdateChannel[1].blocked = bIsBlock
            channels.saveChannel(tUpdateChannel[1])
         end
      end
   end
end

--- Function to get the favorite channels list
-- @return A table with the favorite channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.setFavoriteChannel(tChannel, bIsFav)
   local bFound = false
   local nFound
   for nI = 1, #tChannelList do
      if (tChannelList[nI][1].nNumber == tChannel.nNumber) then
         nFound = nI
         tChannelList[nI][1].bIsFavorite = bIsFav
         local tMask = {['id'] = tChannelList[nI][1].nId} --tFilterMask fields not follow Guideline because is sent to TvStack directly
         local tUpdateChannel = channels.getChannelList(tMask)
         tUpdateChannel[1].favorite = bIsFav
         channels.saveChannel(tUpdateChannel[1])
      end
   end
   if (#tFavoritList > 1) then
      for nI = 1, #tFavoritList do
         if (tFavoritList[nI][1].nNumber == tChannel.nNumber) then
            bFound = true
            if (not bIsFav) then
               table.remove(tFavoritList, nI)
               break
            end
         end
      end
   elseif (#tFavoritList == 1) then
      if (tFavoritList[1][1].nNumber == tChannel.nNumber) then
         bFound = true
         if (not bIsFav) then
            tFavoritList = {}
            return tFavoritList
         end
      end
   end
   if (bIsFav and (not bFound)) then
      nPos = 0
      if (#tFavoritList > 1) then
         --table.sort(tFavoritList, function(tA,tB) return tA[1][1].nNumber < tB[1][1].nNumber end)
         for nI = 1, #tFavoritList do
            if (tChannelList[nFound][1].nNumber < tFavoritList[nI][1].nNumber) then
               nPos = nI
               break
            end
         end
      end
      if (nPos == 0) then
         table.insert(tFavoritList, tChannelList[nFound])
      else
         table.insert(tFavoritList, nPos, tChannelList[nFound])
      end
   end
   return tFavoritList   
end

--- Function to get the favorite channels list
-- @return A table with the favorite channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.getFavoriteChannelList()
   return tFavoritList   
end

--- Function to get the favorite channels list
-- @return A table with the favorite channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.removeChannel(tChannel)
   local tMask = {['number'] = tChannel.nNumber} --tFilterMask fields not follow Guideline because is sent to TvStack directly
   local tRemoveChannel = channels.getChannelList(tMask)
   for nI = 1, #tChannelList do
      if (tChannelList[nI][1].nNumber == tChannel.nNumber) then
         local tCurChan = tChannelApp.getCurrentChannel()
         if (tCurChan.nNumber == tChannelList[nI][1].nNumber and #tChannelList > 1) then
            tChannelApp.selectNextChannel()
         end
         table.remove(tChannelList,nI)
         for nJ = 1, #tFavoritList do
            if (tFavoritList[nJ][1].nNumber == tChannel.nNumber) then
               table.remove(tFavoritList,nJ)
               break
            end
         end
         if (#tChannelList == 0) then
            tChannelApp.cleanScreen()
            tChannelApp.tuneNoChannel()
         end
         for nK = 1, #tRemoveChannel do
            control.eraseChannel(tRemoveChannel[nK].id)
         end
         return true
      end
   end
   if (#tChannelList == 0) then
      tChannelApp.cleanScreen()
      tChannelApp.tuneNoChannel()
   end
   return false
end

function tChannelApp.tuneFirstChannel()
   tChannelApp.tGuiHandlers.onResetAdvice()
   local nId = tPrefenceApp.getLastChanId()
   --tCaptionApp.setCaption(0)
   --control.selectChannel(nId[1])
   bIsTuning = true
   --tChannelApp.resetBlocks()
   local tFilterMask = {}
   tFilterMask.id = nId
   tTempChan = channels.getChannelList(tFilterMask)[1]
   local tChannel = {}
   if (tTempChan.isDigital) then
      tChannel.sName = tTempChan.name
   else
      tChannel.sName = ''
   end
   tChannel.bIsBlock = tTempChan.blocked
   tChannel.nId = tTempChan.id
   tChannel.nNumber = tTempChan.number
   tChannel.nService = tTempChan.service
   tChannel.bIsDigital = tTempChan.isDigital
   tChannelApp.resetBlocks()
   tChannelApp.clearParentalTempUnblock()
   tCaptionApp.setCaption(0)
   control.muteVideo(0,{r=0,g=0,b=0})
   tAudioApp.muteAudio()
   bRet = control.selectChannel(tChannel.nId)
   tChannelApp.checkBlocked(tChannel)
   bIsTuning = true
   tChannelApp.checkParental()
   if (bRet) then
      tLastChannel = tTmpLastChannel
   end
   tChannelApp.tGuiHandlers.onStopAutoOff()
end

---Function to remove all channels
function tChannelApp.removeAllChannels()
   tChannelApp.cleanScreen()
   control.eraseAllChannels()
   tChannelApp.updateChannelList()
   tChannelApp.tGuiHandlers.onStopAutoOff()
   tCaptionApp.setCaption(0)
   tPrefenceApp.setLastChanId(0)
   --control.muteVideo(0,{r=0,g=0,b=0})
   --control.selectChannel(1)
end

--- Function to update the channel list
-- @return A table of channels {nId, nNumber, sName and bIsDigital}
function tChannelApp.updateChannelList(sTunerMode)
   local sTunerMode
   local tFilterMask = {}
   local tTempChannelList = {}--tTempChannelList fields not follow Guideline because is got directly from TvStack
   local tList = {}
   if (sTunerMode == nil) then
      sTunerMode = tPrefenceApp.getTunerMode()
   end
   tFilterMask.source = sTunerMode --tFilterMask fields not follow Guideline because is sent to TvStack directly
   tTempChannelList = channels.getChannelList(tFilterMask)
   for nI = 1, #tTempChannelList do
      local tChannel = {}
      local bFound = false
      for nJ = 1, #tList do
         if ((tList[nJ].nNumber == tTempChannelList[nI].number) and ((tList[nJ].bIsDigital == false) and (tTempChannelList[nI].isDigital == true))) then
            tChannel.sName = tTempChannelList[nI].name
            tChannel.bIsDigital = tTempChannelList[nI].isDigital
            tChannel.bIsFavorite = tTempChannelList[nI].favorite
            tChannel.bIsBlock = tTempChannelList[nI].blocked
            tChannel.bIsSkipped = tTempChannelList[nI].skipped
            tChannel.nId = tTempChannelList[nI].id
            tChannel.nNumber = tTempChannelList[nI].number
            tChannel.nService = tTempChannelList[nI].service
            tList[nJ] = tChannel
         end
         if (tList[nJ].nNumber == tTempChannelList[nI].number) then
            bFound = true
         end
      end
      if (not bFound) then
         if (tTempChannelList[nI].isDigital) then
            tChannel.sName = tTempChannelList[nI].name
         else
            tChannel.sName = ''
         end
         tChannel.bIsDigital = tTempChannelList[nI].isDigital
         tChannel.bIsFavorite = tTempChannelList[nI].favorite
         tChannel.bIsBlock = tTempChannelList[nI].blocked
         tChannel.bIsSkipped = tTempChannelList[nI].skipped
         tChannel.nId = tTempChannelList[nI].id
         tChannel.nNumber = tTempChannelList[nI].number
         tChannel.nService = tTempChannelList[nI].service
         tChannel.bIsOneSeg = tTempChannelList[nI].oneseg
         if (not tTempChannelList[nI].oneseg) then
            table.insert(tList,tChannel)
         end
      end
   end
   table.sort(tList, function(tA,tB) return tA.nNumber < tB.nNumber end)
   tChannelList = {}
   tFavoritList = {}
   nFavLevel = 1
   for nI = 1, #tList do
      tChannelList[nI] = {}
      if (not tList[nI].oneseg) then
         table.insert(tChannelList[nI],tList[nI])
      end
      if (tList[nI].bIsFavorite) then
         tFavoritList[nFavLevel] = {}
         table.insert(tFavoritList[nFavLevel],tList[nI])
      end
      if tList[nI].bIsDigital then
         local tMask = {}
         tMask.source = sTunerMode[1] --tMask fields not follow Guideline because is sent to TvStack directly
         tMask.number = tList[nI].nNumber --tMask fields not follow Guideline because is sent to TvStack directly
         tMask.isDigital = true --tMask fields not follow Guideline because is sent to TvStack directly
         local tTempServiceList = channels.getChannelList(tMask)
         for nJ = 2, #tTempServiceList do
            local tService = {}
            tService.sName = tTempServiceList[nJ].name
            tService.bIsDigital = tTempServiceList[nJ].isDigital
            tService.bIsFavorite = tTempServiceList[nJ].favorite
            tService.bIsBlock = tTempServiceList[nJ].blocked
            tService.bIsSkipped = tTempServiceList[nJ].skipped
            tService.nId = tTempServiceList[nJ].id
            tService.nNumber = tTempServiceList[nJ].number
            tService.nService = tTempServiceList[nJ].service
            tService.bIsOneSeg = tTempServiceList[nJ].oneseg
            if (not tService.bIsOneSeg) then
               table.insert(tChannelList[nI],tService)
               if (tTempServiceList[nJ].favorite) then
                  table.insert(tFavoritList[nFavLevel],tService)
               end
            end
         end
      end
      if (tList[nI].bIsFavorite) then
         nFavLevel = nFavLevel + 1
      end
   end
   if(#tChannelList == 0)then
      tChannelApp.tuneNoChannel()
   end
   --tChannelList = tList
   return tChannelList
end

--- Function to get the current channel
-- @return A table with the current channel {nId, nNumber, sName and bIsDigital}
function tChannelApp.getCurrentChannel()
   local tChannel = {}
   local tTempChan = control.getCurrentChannel()
   if (tTempChan.isDigital) then
      tChannel.sName = tTempChan.name
   else
      tChannel.sName = ''
   end
   tChannel.bIsFavorite = tTempChan.favorite
   tChannel.bIsBlock = tTempChan.blocked
   tChannel.bIsSkipped = tTempChan.skipped
   tChannel.nId = tTempChan.id
   tChannel.nNumber = tTempChan.number
   tChannel.nService = tTempChan.service
   tChannel.bIsDigital = tTempChan.isDigital
   tChannel.sName = tTempChan.name
   tChannel.bIsBlock = tTempChan.blocked
   return tChannel
end

--- Function to get the current event info (Now)
-- @return A table with current event (Now) Info {sName, sShortDescription, sLongDescription, tStartTime, tFinishTime, nParental, nProgress}
function tChannelApp.getCurrentEventInfo(tChannel)
   local tNow = {}
   local tCurrChan
   local tTempNow
   if ( tChannel.nId ) then
      tCurrChan = tChannel
      tTempNow = channels.getCurrentEventInfo(tCurrChan.nId)
   else
      tCurrChan = control.getCurrentChannel()
      tTempNow = channels.getCurrentEventInfo(tCurrChan.id)
   end
   tNow.sName = tTempNow.name
   tNow.sShortDescription = tTempNow.shortDesc
   tNow.sLongDescription = tTempNow.longDesc
   if (tTempNow.start) then
      tNow.tStartTime = tTempNow.start
   end
   if (tTempNow.start and tTempNow.duration) then
      tNow.tFinishTime = tTempNow.start + tTempNow.duration
   end
   if (tTempNow.parental) then
      if(tTempNow.parental.BRA) then
         if(tTempNow.parental.BRA.rating == 'Unknown') then
            tNow.nParental = ''
         else
            tNow.nParental = tTempNow.parental.BRA.rating
         end
      else
         tNow.nParental = ''
      end
   else
      tNow.nParental = ''
   end
   if (tTempNow.start == nil or tTempNow.duration == nil or tTempNow.start == 0 or tTempNow.duration == 0) then
      tNow.nProgress = 0
   else
      tNow.nProgress = math.floor(((os.time() - tTempNow.start) * 100) / tTempNow.duration) -- calc the progress in %
   end
   if (tNow.nProgress > 100) then
      tNow.nProgress = 100
   elseif (tNow.nProgress < 0) then
      tNow.nProgress = 0
   end
   return tNow
end

--- Function to get the next event info (Next)
-- @return A table with next event (Next) Info {sName, sShortDescription, sLongDescription, tStartTime, tFinishTime, nParental, nProgress}
function tChannelApp.getNextEventInfo(tChannel)
   local tNext = {}
   local tCurrChan
   local tTempNext
   if ( tChannel.nId ) then
      tCurrChan = tChannel
      tTempNext = channels.getNextEventInfo(tCurrChan.nId)
   else
      tCurrChan = control.getCurrentChannel()
      tTempNext = channels.getNextEventInfo(tCurrChan.id)
   end
   tNext.sName = tTempNext.name
   tNext.sShortDescription = tTempNext.shortDesc
   tNext.sLongDescription = tTempNext.longDesc
   if (tTempNext.start) then
      tNext.tStartTime = tTempNext.start
   end
   if (tTempNext.start and tTempNext.duration) then
      tNext.tFinishTime = tTempNext.start + tTempNext.duration
   end
   if (tTempNext.parental) then
      if(tTempNext.parental.BRA) then
         if(tTempNext.parental.BRA.rating == 'Unknown') then
            tNext.nParental = ''
         else
            tNext.nParental = tTempNext.parental.BRA.rating
         end
      else
         tNext.nParental = ''
      end
   else
      tNext.nParental = ''
   end
   return tNext
end

--- Function to select/tune one channel 
-- @param tChannel The table of the channel {nId, nNumber, sName and bIsDigital} that will be tuned
-- @return A boolean for success or fail
function tChannelApp.selectLastChannel()
   local bRet = false
   local tCurrChannel = tChannelApp.getCurrentChannel()
   if (tLastChannel.nId ~= nil and tLastChannel.nId ~= tCurrChannel.nId) then
      tCaptionApp.setCaption(0)
      control.muteVideo(0,{r=0,g=0,b=0})
      tChannelApp.resetBlocks()
      bRet = tChannelApp.selectChannel(tLastChannel)
   end
   return bRet
end

--- Function to select/tune one channel 
-- @param tChannel The table of the channel {nId, nNumber, sName and bIsDigital} that will be tuned
-- @return A boolean for success or fail
function tChannelApp.selectChannel(tChannel)
   local bRet = false
   local tTmpLastChannel = tChannelApp.getCurrentChannel()
   if (tChannel.nId ~= nil and (tChannel.nId ~= tTmpLastChannel.nId)) then
      tChannelApp.tGuiHandlers.onResetAdvice()
      tChannelApp.resetBlocks()
      tChannelApp.checkBlocked(tChannel)
      tChannelApp.clearParentalTempUnblock()
      tCaptionApp.setCaption(0)
      control.muteVideo(0,{r=0,g=0,b=0})
      tAudioApp.muteAudio()
      bRet = control.selectChannel(tChannel.nId)
      bIsTuning = true
      tChannelApp.checkParental('L',true)
      if (bRet) then
         tLastChannel = tTmpLastChannel
      end
      tPrefenceApp.setLastChanId(tChannel.nId)
   end
   tChannelApp.tGuiHandlers.onStopAutoOff()
   return bRet
end

--- Function to select/tune analog channel based on a digital channel
--@param tDigitalChannel the Digital Channel
-- @return A boolean for success or fail
function tChannelApp.selectChannelbyPhysNumber(nNumber)
   tChannelApp.tGuiHandlers.onResetAdvice()
   tChannelApp.clearParentalTempUnblock()
   tCaptionApp.setCaption(0)
   control.muteVideo(0,{r=0,g=0,b=0})
   tChannelApp.resetBlocks()
   local bRet = control.selectChannelbyPhysNumber(nNumber,true)
   bIsTuning = true
   tChannelApp.tGuiHandlers.onStopAutoOff()
   return bRet
end

--- Function to select/tune next channel
-- @return A boolean for success or fail
function tChannelApp.selectNextChannel()
   local bRet
   local tChann = tChannelApp.getNextChannel()
   tChannelApp.tGuiHandlers.onResetAdvice()
   tCaptionApp.setCaption(0)
   control.muteVideo(0,{r=0,g=0,b=0})
   tChannelApp.resetBlocks()
   bRet = tChannelApp.selectChannel(tChann)
   return bRet
end

--- Function to select/tune previous channel 
-- @return A boolean for success or fail
function tChannelApp.selectPreviousChannel()
   local bRet
   tChannelApp.tGuiHandlers.onResetAdvice()
   local tChann = tChannelApp.getPreviousChannel()
   tCaptionApp.setCaption(0)
   control.muteVideo(0,{r=0,g=0,b=0})
   tChannelApp.resetBlocks()
   bRet = tChannelApp.selectChannel(tChann)
   return bRet
end

--- Function to get next channel information {nId, nNumber, sName and bIsDigital}
-- This function consider a circular list
-- @param tChan channel to be the reference to the next, if tChan is nil, will return the next channel based on current channel
-- @return A table with the next channel from tChan or the current channel 
function tChannelApp.getNextChannel(tChan)
	
   local tCurChan
   local nTempNext = 0
   local nCurChan = 0
   if (#tChannelList == 1) then
      return tChannelList[1][1]
   end
   if (tChan == nil) then
      tCurChan = tChannelApp.getCurrentChannel()
   else
      tCurChan = tChan
   end
   for nI = 1, #tChannelList do
      if ((nTempNext == 0) and (nCurChan == 0) and (not tChannelList[nI][1].bIsSkipped)) then
         nTempNext = nI
      end
      if (tCurChan.nNumber == tChannelList[nI][1].nNumber) then
         nCurChan = nI
      end
      if ((nCurChan <= nI) and (nCurChan > 0)) then
         if (nI < #tChannelList) then
            if (not tChannelList[nI+1][1].bIsSkipped) then
               return tChannelList[nI+1][1]
            end
         else
            if (not tChannelList[1][1].bIsSkipped) then
               return tChannelList[1][1]
            end
         end
      end
   end
   if (nTempNext > 0) then 
      return tChannelList[nTempNext][1]
   else
      return tCurChan
   end
end

--- Function to get previous channel information {nId, nNumber, sName and bIsDigital}
-- This function consider a circular list
-- @param tChan channel to be the reference to the previous, if tChan is nil, will return the previous channel based on current channel
-- @return A table with the previous channel from tChan or the current channel 
function tChannelApp.getPreviousChannel(tChan)
   local tCurChan
   local nTempNext = 0
   local nCurChan = 0
   if (#tChannelList == 1) then
      return tChannelList[1][1]
   end
   if (tChan == nil) then
      tCurChan = tChannelApp.getCurrentChannel()
   else
      tCurChan = tChan
   end
   for nI = #tChannelList, 1, -1 do
      if ((nTempNext == 0) and (nCurChan == 0) and (not tChannelList[nI][1].bIsSkipped)) then
         nTempNext = nI
      end
      if (tCurChan.nNumber == tChannelList[nI][1].nNumber) then
         nCurChan = nI
      end
      if ((nCurChan >= nI) and (nCurChan > 0)) then
         if (nI > 1) then
            if (not tChannelList[nI-1][1].bIsSkipped) then
               return tChannelList[nI-1][1]
            end
         else
            if (not tChannelList[#tChannelList][1].bIsSkipped) then
               return tChannelList[#tChannelList][1]
            end
         end
      end
   end
   if (nTempNext > 0) then 
      return tChannelList[nTempNext][1]
   else
      return tCurChan
   end
end

--- Function to select/tune one channel by the number
-- @param nNumber the channel numbere
-- @param nService the channel service number (only if Digital Channel, nil if Analog Channel)
-- @return boolean True if the command was sent successfully, false if some error occured.
function tChannelApp.selectChannelByNumber(nNumber,nService)
   local bRet = false
   local tTmpLastChannel
   if (nNumber ~= nil) then
      tTmpLastChannel = tChannelApp.getCurrentChannel()
      for nI = 1, #tChannelList do
         if (tChannelList[nI][1].nNumber == nNumber) then
            tChannelApp.tGuiHandlers.onStopAutoOff()
            if (nService == nil) then
               tChannelApp.resetBlocks()
               tChannelApp.tGuiHandlers.onResetAdvice()
               tChannelApp.checkBlocked(tChannelList[nI][1])
               tChannelApp.clearParentalTempUnblock()
               tCaptionApp.setCaption(0)
               control.muteVideo(0,{r=0,g=0,b=0})
               bRet = control.selectChannel(tChannelList[nI][1].nId)
               bIsTuning = true
               tChannelApp.checkParental('L')
               if (bRet) then
                  tLastChannel = tTmpLastChannel
               end
               tChannelApp.tGuiHandlers.onStopAutoOff()
               tPrefenceApp.setLastChanId(tChannelList[nI][1].nId)
            else
               for nJ = 1, #tChannelList[nI] do
                  if (nService == tChannelList[nI][nJ].nService) then
                     tChannelApp.resetBlocks()
                     tChannelApp.tGuiHandlers.onResetAdvice()
                     tChannelApp.checkBlocked(tChannelList[nI][nJ])
                     tChannelApp.clearParentalTempUnblock()
                     tCaptionApp.setCaption(0)
                     control.muteVideo(0,{r=0,g=0,b=0})
                     bRet = control.selectChannel(tChannelList[nI][nJ].nId)
                     bIsTuning = true
                     tChannelApp.checkParental('L')
                     if (bRet) then
                        tLastChannel = tTmpLastChannel
                     end
                     tChannelApp.tGuiHandlers.onStopAutoOff()
                     tPrefenceApp.setLastChanId(tChannelList[nI][nJ].nId)
                  end
               end
            end
         end
      end
   end
   return bRet
end

--- Start a Channel Scan
-- @param sSource The source Scan - Air/Cable/..
-- @return boolean True if the command was sent successfully, false if some error occurred.
function tChannelApp.startScan(sSource)
   tPrefenceApp.setTunerMode(sSource) --@TODO
   tCaptionApp.setCaption(0)
   control.muteVideo(0,{r=0,b=0,g=0})
   local tFilterMask = {}
   tScanStatus = {}
   tScanStatus.nChFound = 0
   tScanStatus.nChUpdated = 0
   tScanStatus.sScanSource = sSource
   tScanStatus.tChanFound = {}
   tScanStatus.tScanTempChan = {}
   tFilterMask.source = sSource
   tScanStatus.bIsFrist = true
   if (#tChannelList > 0) then
      local tTempChan = control.getCurrentChannel()
      tScanStatus.bIsFrist = false
   end
   tScanStatus.tScanTempChan = channels.getChannelList(tFilterMask)
   if (#tScanStatus.tScanTempChan == 0) then
      tScanStatus.bIsFrist = true
   end
   if (tScanStatus.sScanSource == 'Air') then
      return control.startChannelScan(tScanStatus.sScanSource,4,true)
   else
      return control.startChannelScan(tScanStatus.sScanSource,0,true)
   end
end

--- Function to force stop the Scan
-- @return boolean True if the command was sent successfully, false if some error occured.
function tChannelApp.stopScan()
   return control.stopChannelScan(tScanStatus.sScanSource)
end

--- Function to get if channel is blocked by parental
-- @return number with parental value - 0 to free or invalid.
function tChannelApp.getCurrParentalRating()
   return nCurrParental
end

--- Function to get if channel is blocked by parental
-- @return boolean True if blocked.
function tChannelApp.isNoSignal()
   return bIsNoSignal
end

--- Function to get if channel is blocked by parental
-- @return boolean True if blocked.
function tChannelApp.isNoTransmission()
   return bIsNoTransmission
end

--- Function to get if channel is blocked by parental
-- @return boolean True if blocked.
function tChannelApp.isParentalBlock()
   return bIsParental
end

--- Function to get if channel is blocked by user
-- @return boolean True if blocked.
function tChannelApp.isBlocked()
   return bIsBlock
end

--- Function to verify if channel is blocked and call (show/hide) GUI advice
-- @return boolean True if blocked.
function tChannelApp.clearParentalTempUnblock()
      sTempParental = 'OFF'
end

--- Function to verify if channel is blocked and call (show/hide) GUI advice
-- @return boolean True if blocked.
function tChannelApp.parentalTempUnblock()
   if (bIsParental) then
      bIsParental = false
      sTempParental = nCurrParental
      tChannelApp.tGuiHandlers.onStopParental()
   end
   if (bIsBlock) then
      tChannelApp.tGuiHandlers.onStopBlock()
   elseif (bIsNoSignal) then
      tChannelApp.tGuiHandlers.onStartNoSignal()
   elseif (bIsNoTransmission) then
      tChannelApp.tGuiHandlers.onStartNoTransmission()
   else
      tAudioApp.unmuteAudio()
      tCaptionApp.muteCaption(false,'advice')
      control.unmuteVideo(0)
   end
end

--- Function to verify if channel is blocked and call (show/hide) GUI advice
-- @return boolean True if blocked.
function tChannelApp.tempUnblock()
   if (bIsBlock) then
      bIsBlock = false
      tChannelApp.tGuiHandlers.onStopBlock()
   end
   if (bIsParental) then
      tChannelApp.tGuiHandlers.onStartParental()
   elseif (bIsNoSignal) then
      tChannelApp.tGuiHandlers.onStartNoSignal()
   elseif (bIsNoTransmission) then
      tChannelApp.tGuiHandlers.onStartNoTransmission()
   else
      tAudioApp.unmuteAudio()
      tCaptionApp.muteCaption(false,'advice')
      control.unmuteVideo(0)
   end
end

--- Function to verify if channel is blocked and call (show/hide) GUI advice
-- @return boolean True if blocked.
function tChannelApp.checkParental(nRating,bForceNoUnmute)
   local nTempParental = 0
   local tRateParser = {}
   tRateParser['OFF'] = 0
   tRateParser['L'] = 1
   tRateParser['10'] = 2
   tRateParser['12'] = 3
   tRateParser['14'] = 4
   tRateParser['16'] = 5
   tRateParser['18'] = 6
   
   if(not nRating) then
      nRating = ''
      local tRate = channels.getCurrentParental()
      if (tRate.BRA) then
         if (tRate.BRA.rating == 'Unknow') then
            nRating = ''
         else
            nRating = tRate.BRA.rating
         end
      end
   end
   
   if (nRating == '' or nRating == 0 or nRating == '0') then
      nRating = 'L'
   end
   
   nCurrParental = tRateParser[tostring(nRating)]
   nTempParental = tRateParser[sTempParental]
   if ((not nCurrParental) or (nCurrParental < 2)) then
      if (bIsParental) then
         bIsParental = false
         if (not bForceNoUnmute and not bIsBlock) then
            tAudioApp.unmuteAudio()
            tCaptionApp.muteCaption(false,'advice')
            control.unmuteVideo(0)
         end
         tChannelApp.tGuiHandlers.onStopParental()
      end
   else
      local nRate = tRateParser[tostring(tPrefenceApp.getParentalLevel())]
      if ((nRate > 0) and (nRate <= nCurrParental)) then
         if (not((nTempParental > 0) and (nTempParental >= nCurrParental))) then
            sTempParental = 'OFF'
            bIsParental = true
            tAudioApp.muteAudio()
            tCaptionApp.muteCaption(true,'advice')
            control.muteVideo(0,{r=0,b=0,g=0})
            nCurrParental = tostring(nRating)
            tChannelApp.tGuiHandlers.onStartParental()
         end
      else
         if (bIsParental) then
            bIsParental = false
            if (not bForceNoUnmute and not bIsBlock) then
               tAudioApp.unmuteAudio()
               tCaptionApp.muteCaption(false,'advice')
               control.unmuteVideo(0)
            end
            tChannelApp.tGuiHandlers.onStopParental()
         end
      end
   end
   
   nCurrParental = tostring(nRating)
end

--- Function to verify if channel is blocked and call (show/hide) GUI advice
-- @return boolean True if blocked.
function tChannelApp.checkBlocked(tChannel,sSource)
   if (not tChannel) then
      if (sSource) then
         if ((sSource ~= 'Air') and (sSource ~= "Cable") and (sSource ~= "TV")) then
            if (bIsBlock) then
               bIsBlock = false
               tChannelApp.tGuiHandlers.onStopBlock()
            end
            return bIsBlock
         end
      end
      tChannel = tChannelApp.getCurrentChannel()
   end
   if (tChannel.bIsBlock) then
      bIsBlock = true
      tAudioApp.muteAudio()
      tCaptionApp.muteCaption(true,'advice')
      control.muteVideo(0,{r=0,b=0,g=0})
      tChannelApp.tGuiHandlers.onStartBlock()
   else
      if (bIsBlock) then
         bIsBlock = false
         tChannelApp.tGuiHandlers.onStopBlock()
      end
      if (not bIsParental) then
         tAudioApp.unmuteAudio()
         tCaptionApp.muteCaption(false,'advice')
         control.unmuteVideo(0)
      end
   end
   return bIsBlock
end

function tChannelApp.checkAdvice(tSource)
   if (tSource.sName ~= "TV") then
      tChannelApp.checkParental(0)
   end
   tChannelApp.checkBlocked(nil,tSource.sName)
   if (bIsNoSignal) then
      bIsNoSignal = false
      if (not bIsBlock) then
         tCaptionApp.muteCaption(false,'advice')
         control.unmuteVideo(0)
      end
      tChannelApp.tGuiHandlers.onStopNoSignal()
   elseif (bIsNoTransmission) then
      if (not bIsBlock) then
         tCaptionApp.muteCaption(false,'advice')
         control.unmuteVideo(0)
      end
      bIsNoTransmission = false
      tChannelApp.tGuiHandlers.onStopNoTransmission()
   end
end

function tChannelApp.checkBlueScreen()
   if(not tChannelApp.getCurrentChannel().bIsDigital) then
      if(bIsNoSignal) then
         if (tPrefenceApp.getBlueScreen()) then
            tCaptionApp.muteCaption(true,'advice')
            control.muteVideo(0,{r=0,g=0,b=255})
         else
            tCaptionApp.muteCaption(false,'advice')
            control.unmuteVideo(0)
         end         
      end
   end   
end

function tChannelApp.checkPoweOff()
   tChannelApp.tGuiHandlers.checkAutoOff()
end

--Function to clean the screen
function tChannelApp.cleanScreen()
   if (bIsBlock) then
      bIsBlock = false
      tChannelApp.tGuiHandlers.onStopBlock()
   end
   if(bIsNoSignal)then
      bIsNoSignal = false
      tChannelApp.tGuiHandlers.onStopNoSignal()
   end
   if(bIsParental)then
      bIsParental = false
      tChannelApp.tGuiHandlers.onStopParental()
   end
   if(bIsNoTransmission)then
      bIsNoTransmission = false
      tChannelApp.tGuiHandlers.onStopNoTransmission()
   end
   --pay attention to under line.
   tCaptionApp.muteCaption(false,'advice')
   control.unmuteVideo(0)
end

function tChannelApp.tuneNoChannel()
   bIsTuning = true
   tChannelApp.tGuiHandlers.onStopAutoOff()
	return control.selectChannelbyPhysNumber(0,true)
end
------------------------------------------------------------------------
--handlers implemented
local tHandlers = {}

-- Handler implementation of handlers.onChannelScanStarted(source)
-- @param sSource The source to do a Scan - Air/Cable/..
function tHandlers.onChannelScanStarted(sSource)
   tChannelApp.tGuiHandlers.onChannelScanStarted()
end

-- Handler implementation of handlers.onChannelFound(sSource, channelNumber)
-- @param sSource The source to do a Scan - Air/Cable
-- @param channelNumber The number of the found channel
-- @param bIsDigital Indicate if the found channel is Digital or Analog
function tHandlers.onChannelFound(sSource, nChannelNumber, physicalNumber, numberOfServices, channelName, sourceType, bIsDigital)
   local nFoundAtList = 0
   local bIsBlock = false
   local bIsSkip = false
   local bIsFav = false
   local nChNum
   if (bIsDigital) then
      nChNum = math.floor(nChannelNumber / 10)
   else
      nChNum = nChannelNumber
   end
   local tTempChan = {}
   for nI = 1, #tScanStatus.tScanTempChan do
      if ((physicalNumber == tScanStatus.tScanTempChan[nI].physNumber)) then
         return
      end
   end
   
   for nI = 1, #tScanStatus.tScanTempChan do
      if (tScanStatus.tScanTempChan[nI].number == nChNum and (not tScanStatus.tScanTempChan[nI].isDigital) and bIsDigital) then 
         nFoundAtList = tScanStatus.tScanTempChan[nI].number
         bIsBlock = tScanStatus.tScanTempChan[nI].blocked
         bIsSkip = tScanStatus.tScanTempChan[nI].skipped
         bIsFav = tScanStatus.tScanTempChan[nI].favorite
      end
   end

   if (nFoundAtList > 0 and not tScanStatus.bIsFrist) then
      tScanStatus.nChUpdated = tScanStatus.nChUpdated + 1
      tChannelApp.tGuiHandlers.onChannelFound((tScanStatus.nChFound + tScanStatus.nChUpdated), nChannelNumber, bIsDigital)
      --@TODO sync block, fav and skip with updated channels
      local tFilterMask = {}
      tFilterMask.source = sSource
      tFilterMask.number = nChNum
      --control.setBlockChannels(tFilterMask, isBlock)
      --control.setSkipChannels(tFilterMask, isSkip)
      --control.setFavoriteChannels(tFilterMask, isFav)
      local tTempChannel = {}
      --sSource, nChannelNumber, physicalNumber, numberOfServices, channelName, sourceType, bIsDigital
      tTempChannel.isDigital = bIsDigital
      tTempChannel.source = sSource
      tTempChannel.service = 1
      tTempChannel.number = nChNum
      tTempChannel.sourceType = sourceType
      tTempChannel.name = channelName
      tTempChannel.blocked = false
      tTempChannel.skipped = false
      tTempChannel.favorite = false
      tTempChannel.physNumber = physicalNumber
      table.insert(tScanStatus.tScanTempChan,tTempChannel)
      --
   elseif (tScanStatus.tChanFound[nChNum] == nil) then
      tScanStatus.tChanFound[nChNum] = true
      tScanStatus.nChFound = tScanStatus.nChFound + 1
      tChannelApp.tGuiHandlers.onChannelFound((tScanStatus.nChFound + tScanStatus.nChUpdated), nChannelNumber, bIsDigital)
      local tTempChannel = {}
      --sSource, nChannelNumber, physicalNumber, numberOfServices, channelName, sourceType, bIsDigital
      tTempChannel.isDigital = bIsDigital
      tTempChannel.source = sSource
      tTempChannel.service = 1
      tTempChannel.number = nChNum
      tTempChannel.sourceType = sourceType
      tTempChannel.name = channelName
      tTempChannel.blocked = false
      tTempChannel.skipped = false
      tTempChannel.favorite = false
      tTempChannel.physNumber = physicalNumber
      table.insert(tScanStatus.tScanTempChan,tTempChannel)
   end
end

-- Handler implementation of handlers.onChannelScanProgressUpdate(sSource, nProgress)
-- @param sSource the source to do a Scan - Air/Cable
-- @param nProgress how many channels have been scanned.
-- @param nChannelNumber the number of the actual channel virtual if digital, physical if analog.
--function tHandlers.onChannelScanProgressUpdate(sSource, nProgress, nChannelNumber)
function tHandlers.onChannelScanProgressUpdate(sSource, nProgress, nMax, nChannelNumber)
   local nProg = 0
   nProg = ( nProgress * 100 ) / nMax
   nProg = math.floor(nProg)
   tChannelApp.tGuiHandlers.onChannelScanProgressUpdate(nProg)
end

-- Handler implementation of handlers.onChannelScanEnded(sSource, nCause)
-- @param sSource the source to do a Scan - Air/Cable
-- @param nCause code indicating the cause of the end of the channel scan
function tHandlers.onChannelScanEnded(sSource, nCause)
   local tFilterMask = {}
   if ( not bIsBlock and not bIsParental) then
      control.unmuteVideo(0)
      tAudioApp.unmuteAudio()
   end
   tScanStatus.tChanFound = nil
   tScanStatus.tChanFound = {}
   tScanStatus.tScanTempChan = nil
   tScanStatus.tScanTempChan = {}
   tFilterMask.source = sSource
   tScanStatus.tScanTempChan = channels.getChannelList(tFilterMask)
   local nCounter = 0
   for nI = 1, #tScanStatus.tScanTempChan do
      if (not tScanStatus.tChanFound[tScanStatus.tScanTempChan[nI].number]) then
         nCounter = nCounter + 1
         tScanStatus.tChanFound[tScanStatus.tScanTempChan[nI].number] = true
      end
   end
   tChannelApp.updateChannelList(sSource)
   if(#tChannelList > 0) then
      tChannelApp.tuneDefaultChannel()
   end
   tChannelApp.tGuiHandlers.onChannelScanEnded(nCounter, (tScanStatus.nChFound + tScanStatus.nChUpdated), tScanStatus.nChFound, tScanStatus.nChUpdated)
   tScanStatus = {}
end

-- Handler implementation of handlers.onTuneFinished(sSource)
-- @param sSource The source that was tuned.
function tHandlers.onTuneFinished(sSource)
   bIsTuning = false
   tChannelApp.checkBlocked(nil,sSource)
   --tChannelApp.tGuiHandlers.onStopAutoOff()
   tChannelApp.tGuiHandlers.onTuneFinished(sSource)
   --tHandlers.onSignalOK(sSource)
   
   if ( not bIsBlock and not bIsParental) then
      control.unmuteVideo(0)
      tAudioApp.unmuteAudio()
   end
end

-- Notification of signal OK
function tHandlers.onSignalOK(sSource, nChannelId)
   tChannelApp.checkBlocked(nil,sSource)
   if (bIsNoSignal) then
      bIsNoSignal = false
      tChannelApp.tGuiHandlers.onStopNoSignal()
   elseif (bIsNoTransmission) then
      bIsNoTransmission = false
      tChannelApp.tGuiHandlers.onStopNoTransmission()
   end
   if ( not bIsBlock and not bIsParental) then
      tCaptionApp.muteCaption(false,'advice')
      control.unmuteVideo(0)
      tAudioApp.unmuteAudio()
   end
   tChannelApp.tGuiHandlers.onStopAutoOff()
   tChannelApp.tGuiHandlers.onTuneFinished(sSource)
end

-- Notification of signal lost
function tHandlers.onSignalLost(sSource, nChannelId)
   local sCurrSrc
   local tSource = control.getCurrentSource()
   if (tSource['type'] == 'Tuner') then
      sCurrSrc = 'TV'
   else
      sCurrSrc = tSource['name']
   end
   tChannelApp.tGuiHandlers.onStartAutoOff(sCurrSrc)
   bIsNoSignal = true
   local tCurrChan = tChannelApp.getCurrentChannel()
   if (tCurrChan.bIsDigital or sCurrSrc ~= 'TV') then
      tCurrChan.bIsDigital = true
      tCaptionApp.muteCaption(true,'advice')
      control.muteVideo(0,{r=0,b=0,g=0})
      tAudioApp.muteAudio()
   else
      tChannelApp.tGuiHandlers.onStopNoSignal()
      if (tPrefenceApp.getBlueScreen() and (not bIsBlock)) then
         tCaptionApp.muteCaption(true,'advice')
         control.muteVideo(0,{r=0,b=255,g=0})
         tAudioApp.muteAudio()
      end
   end
   if (bIsParental) then
      bIsParental = false
      tChannelApp.tGuiHandlers.onStopParental()
   end
   if (bIsNoTransmission) then
      bIsNoTransmission = false
      tChannelApp.tGuiHandlers.onStopNoTransmission()
   end
   tChannelApp.tGuiHandlers.onStartNoSignal(tCurrChan.bIsDigital)
end

-- Notification of signal lost
function tHandlers.onTuneError(sSource, nChannelId)
   local sCurrSrc
   local tSource = control.getCurrentSource()
   if (tSource['type'] == 'Tuner') then
      sCurrSrc = 'TV'
   else
      sCurrSrc = tSource['name']
   end
   tChannelApp.tGuiHandlers.onStartAutoOff(sCurrSrc)
   bIsNoTransmission = true
   tCaptionApp.muteCaption(true,'advice')
   control.muteVideo(0,{r=0,b=0,g=0})
   if (bIsParental) then
      bIsParental = false
      tChannelApp.tGuiHandlers.onStopParental()
   end
   if (bIsNoSignal) then
      bIsNoSignal = false
      tChannelApp.tGuiHandlers.onStopNoSignal()
   end
   if (tChannelApp.getCurrentChannel().bIsDigital) then
      tChannelApp.tGuiHandlers.onStartNoTransmission()
   end
end

-- Notification of signal lost
function tHandlers.onParentalChanged(tRating)
   local sRating
   if (tRating.BRA) then
      if (tRating.BRA.rating == 'Unknown') then
         sRating = ''
      else
         sRating = tRating.BRA.rating
      end
      tChannelApp.checkParental(sRating)
   end
end

handlers.onSignalOK = tHandlers.onSignalOK
handlers.onSignalLost = tHandlers.onSignalLost
handlers.onTuneError = tHandlers.onTuneError
handlers.onParentalChanged = tHandlers.onParentalChanged
handlers.onChannelFound = tHandlers.onChannelFound
handlers.onChannelScanEnded = tHandlers.onChannelScanEnded
handlers.onChannelScanProgressUpdate = tHandlers.onChannelScanProgressUpdate
handlers.onChannelScanStarted = tHandlers.onChannelScanStarted
handlers.onTuneFinished =  tHandlers.onTuneFinished
------------------------------------------------------------------------
--handlers to GUI
tChannelApp.tGuiHandlers = {}

--- Callback function to send a notification when signal is LOST.
function tChannelApp.tGuiHandlers.onResetAdvice()
end

--- Callback function to send a notification when signal is LOST.
function tChannelApp.tGuiHandlers.onStartNoTransmission()
end

--- Callback function to send a notification when signal is OK.
function tChannelApp.tGuiHandlers.onStopNoTransmission()
end

--- Callback function to send a notification when signal is LOST.
function tChannelApp.tGuiHandlers.onStartNoSignal()
end

--- Callback function to send a notification when signal is OK.
function tChannelApp.tGuiHandlers.onStopNoSignal()
end

--- Callback function to send a notification when the block started
function tChannelApp.tGuiHandlers.onStartBlock()
end

--- Callback function to send a notification when the block finished
function tChannelApp.tGuiHandlers.onStopBlock()
end

--- Callback function to send a notification when the parental rating started
-- @param nChFound the total number of channels found, including added and updated.
function tChannelApp.tGuiHandlers.onStartParental()
end

--- Callback function to send a notification when the parental rating finished
function tChannelApp.tGuiHandlers.onStopParental()
end

--- Callback function to send a notification when a scan have been started.
function tChannelApp.tGuiHandlers.onChannelScanStarted()
end

--- Callback function to send a notification when a channel is found.
-- @param nChFound the total number of channels found, including added and updated.
-- @param nChannelNumber number that represents the channel - the physical(Analog) or virtual(Digital).
-- @param bIsDigital indicates if the channel is Digital or not.
function tChannelApp.tGuiHandlers.onChannelFound(nChFound, nChannelNumber, bIsDigital)
end

--- Callback function to update the scan progress.
-- @param nProgress The number in % of scanning progress.
function tChannelApp.tGuiHandlers.onChannelScanProgressUpdate(nProgress)
end

--- Callback function to send a notification when finish the channel scan.
-- @param nTotalList the total number of channels at channel list
-- @param nTotalFound total of channels changed during the scan 
-- @param nChFound total of channels add at channel list
-- @param nChUpdated total of updated channels during channel scan
function tChannelApp.tGuiHandlers.onChannelScanEnded(nTotalList, nTotalFound, nChFound, nChUpdated)
end

--- Callback function to send a notification when the TV Stack has finished tuning a previously selected channel.
-- @param sSource The source that was tuned (Air/Cable/...).
function tChannelApp.tGuiHandlers.onTuneFinished(sSource)
end

--- Callback function to send a notification when the TV Stack has finished tuning a previously selected channel.
-- @param sSource The source that was tuned (Air/Cable/...).
function tChannelApp.tGuiHandlers.onStartAutoOff(sSource)
end

--- Callback function to send a notification when the TV Stack has finished tuning a previously selected channel.
-- @param sSource The source that was tuned (Air/Cable/...).
function tChannelApp.tGuiHandlers.onStopAutoOff()
end

--- Callback function to send a notification when the TV Stack has finished tuning a previously selected channel.
-- @param sSource The source that was tuned (Air/Cable/...).
function tChannelApp.tGuiHandlers.checkAutoOff()
end
------------------------------------------------------------------------
return tChannelApp
